﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using ESRI.ArcGIS.Geodatabase;
using System.Runtime.InteropServices;
using ESRI.ArcGIS.Geoprocessing;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Geometry;

namespace CheckData
{
    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();
        }
        /// <summary>
        /// 打开数据处理
        /// </summary>
        private void toolStripButtonStart_Click(object sender, EventArgs e)
        {
            OpenFileDialog dialog = new OpenFileDialog();
            dialog.Filter = "SHAPE文件(*.SHP)|*.SHP";
            dialog.Multiselect = true;
            if (dialog.ShowDialog(this) != DialogResult.OK) return;

            int num = 0;
            CheckSame checksame = new CheckSame();
            foreach (string file in dialog.FileNames) {
                IFeatureWorkspace workspace = Gis.GetWorkSpaceFromSHP(file);
                IFeatureClass fclass = workspace.OpenFeatureClass(System.IO.Path.GetFileName(file));
                ((IWorkspaceEdit)workspace).StartEditing(false);
                ((IWorkspaceEdit)workspace).StartEditOperation();


                ShowMessage(string.Format("{0}: 修复图层[{1}/{2}] {3} .. \r\n", DateTime.Now.ToString("MM/dd HH:mm:ss"), ++num, dialog.FileNames.Length, System.IO.Path.GetFileName(file)), Color.Blue);
                Application.DoEvents();
                Repair(new List<IFeatureClass>() { fclass });
                Application.DoEvents();
                ShowMessage(string.Format("{0}: 处理重复数据 {1} .. ", DateTime.Now.ToString("MM/dd HH:mm:ss"), System.IO.Path.GetFileName(file)), Color.Blue);
                Application.DoEvents();
                checksame.Check1(fclass, new string[] { "BM" });
                Application.DoEvents();
                ShowMessage(string.Format("OK\r\n", DateTime.Now.ToString("MM/dd HH:mm:ss")), Color.Blue);

                ((IWorkspaceEdit)workspace).StopEditOperation();
                ((IWorkspaceEdit)workspace).StopEditing(true);
            }

            ShowMessage(string.Format("{0}: 完成.\r\n", DateTime.Now.ToString("MM/dd HH:mm:ss")), Color.Blue);
            

        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="message"></param>
        /// <param name="color"></param>
        private void ShowMessage(string message, Color color)
        {
            int len = txtMessage.Text.Length;
            if (len > 0) txtMessage.SelectionStart = len;
            txtMessage.SelectionColor = color;
            txtMessage.ScrollToCaret();
            txtMessage.AppendText(message);
        }


        /// <summary>
        /// 修复
        /// </summary>
        /// <param name="workspace"></param>
        private void Repair(List<IFeatureClass> lstFeatureClass)
        {
            // 
            foreach (IFeatureClass featureClass in lstFeatureClass) {
                if (featureClass == null ||
                    (featureClass.ShapeType != esriGeometryType.esriGeometryPolygon &&
                     featureClass.ShapeType != esriGeometryType.esriGeometryPolyline)) continue;
                // 
                //ShowMessage(string.Format("{0}: 正在修复图层 .. {1}", DateTime.Now.ToString("MM/dd HH:mm:ss"), ((IDataset)featureClass).Name), Color.Blue);
                string message;
                bool result = GPExecute("RepairGeometry_management", new object[] { featureClass }, out message);
                //ShowMessage(result ? "OK.\r\n" : "Fail.\r\n", result ? Color.Green : Color.Red);
                // 由于部分数据无法修复长度为0的，所以手工处理
                Repair(featureClass);

                Application.DoEvents();
            }
        }
        /// <summary>
        /// 手工修复
        /// </summary>
        /// <param name="featureClass"></param>
        private void Repair(IFeatureClass featureClass)
        {
            IQueryFilter filter = new QueryFilterClass();
            filter.SubFields = featureClass.OIDFieldName + "," + featureClass.ShapeFieldName;
            IFeatureCursor cursor = featureClass.Search(filter, true);
            for (IFeature feature = cursor.NextFeature(); feature != null; feature = cursor.NextFeature()) {
                if (featureClass.ShapeType == esriGeometryType.esriGeometryPolyline) {
                    IPolyline line = feature.Shape as IPolyline;
                    if (line.IsEmpty || line.Length < 0.001) {
                        ((ITable)featureClass).DeleteSearchedRows(new QueryFilterClass()
                        { WhereClause = string.Format("{0}={1}", featureClass.OIDFieldName, feature.OID) });
                        ShowMessage(string.Format("Deleted feature {0} because of short segments\r\n", feature.OID), Color.Green);
                    }
                }
                else if (featureClass.ShapeType == esriGeometryType.esriGeometryPolygon) {
                    IArea area = feature.Shape as IArea;
                    if (area.Area < 0.001) {
                        ((ITable)featureClass).DeleteSearchedRows(new QueryFilterClass()
                        { WhereClause = string.Format("{0}={1}", featureClass.OIDFieldName, feature.OID) });
                        ShowMessage(string.Format("Deleted feature {0} because of short segments\r\n", feature.OID), Color.Green);
                    }
                }
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="name"></param>
        /// <param name="args"></param>
        /// <param name="message"></param>
        /// <returns></returns>
        private bool GPExecute(string name, object[] args, out string message)
        {
            IGeoProcessor processor = new GeoProcessorClass() { OverwriteOutput = true };
            IVariantArray ipValues = new VarArrayClass();
            IGeoProcessorResult result = null;
            try {
                // 参数
                foreach (object obj in args) ipValues.Add(obj);
                // 执行
                result = processor.Execute(name, ipValues, null) as IGeoProcessorResult;
                message = GetMessage(processor);
                if (result == null || result.Status != esriJobStatus.esriJobSucceeded) return false;
                else return true;
            }
            catch (Exception ex) {
                message = GetMessage(processor);
                message += Environment.NewLine + ex.Message;
                return false;
            }
            finally {
                if (processor != null) Marshal.ReleaseComObject(processor);
                if (ipValues != null) Marshal.ReleaseComObject(ipValues);
                if (result != null) Marshal.ReleaseComObject(processor);
            }
        }
        /// <summary>
        /// 读取信息
        /// </summary>
        /// <param name="processor"></param>
        /// <returns></returns>
        private string GetMessage(IGeoProcessor processor)
        {
            StringBuilder builder = new StringBuilder();
            for (int i = 0; i < processor.MessageCount; i++){
                builder.Append(processor.GetMessage(i));
                builder.Append(Environment.NewLine);
            }
            return builder.ToString();
        }
    }
}
